﻿using LitJson;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.SceneManagement;

/// <summary>
/// 应该在舰船被添加进来的时候就将他们分门别类的放在不同的数组，这样可以减少搜索的压力
/// </summary>
class ShipManager
{
    public int NumShips { get { return m_Ships.Count; } }

    public static ShipManager Instance = new ShipManager();
    List<Ship> m_Ships = new List<Ship>();
    public List<Ship> m_NoShps = new List<Ship>();
    public List<Ship> m_ShipsPerfab = new List<Ship>();
    string m_ExternResourcePath = "./ExternalResource/";
    ShipManager ()
    {
        SceneManager.sceneUnloaded += OnUnSceneLoaded;
    }

    bool Inited = false;
    public void Init()
    {

        if (Inited == true)
            return;
        Inited = true;

        //  存储舰船的预制体
        var object2 = Resources.LoadAll("Perfabs/Ships/Common/");
        List<GameObject> objs = new List<GameObject>();
        for (int i = 0; i < object2.Length; ++i)
        {
            var gobj = object2[i] as GameObject;
            if (gobj != null && gobj.GetComponent<Ship>() != null)
            {
                m_ShipsPerfab.Add(gobj.GetComponent<Ship>());
            }
        }
        var object3 = Resources.LoadAll("Perfabs/Ships/NetWorkFriend/");
        objs = new List<GameObject>();
        for (int i = 0; i < object3.Length; ++i)
        {
            var gobj = object3[i] as GameObject;
            if (gobj != null && gobj.GetComponent<Ship>() != null)
            {
                m_ShipsPerfab.Add(gobj.GetComponent<Ship>());
            }
        }

#if UNITY_ANDROID
        m_ExternResourcePath = Application.persistentDataPath+"/" + m_ExternResourcePath;
#endif
        LoadExternalResouceConfig();
    }

    public void LoadExternalResouceConfig()
    {
        string data;
        string configFilePath = m_ExternResourcePath + "ExternalResouce.conf";
        if (!File.Exists(configFilePath))
        {
            return;
        }

        using (FileStream fs = new FileStream(configFilePath, FileMode.Open, FileAccess.Read))
        {
            FileInfo info = new System.IO.FileInfo(configFilePath);
            byte[] array = new byte[info.Length];
            fs.Read(array, 0, (int)info.Length);
            fs.Close();
            data = System.Text.Encoding.Default.GetString(array);
        }
        if (data.Length == 0)
            return;
        JsonData jsonData = JsonMapper.ToObject(data);

        //// 
        if (jsonData == null)
            return;

        var jsonRootObj = jsonData.ValueAsObject();
        if (jsonRootObj.ContainsKey("Textures"))
        {
            var jsonTextures = jsonRootObj["Textures"].ValueAsObject();
            if (jsonTextures.ContainsKey("Ships"))
            {
                var jsonShips = jsonTextures["Ships"].ValueAsObject();
                for (int i = 0; i < m_ShipsPerfab.Count; ++i)
                {
                    var path = m_ShipsPerfab[i].m_Path;
                    if (jsonShips.ContainsKey(path))
                    {
                        string newPath = jsonShips[path].ValueAsString();
                        newPath = m_ExternResourcePath + "/Textures/Ships/" + newPath;

                        var oldSprite = m_ShipsPerfab[i].GetComponent<SpriteRenderer>().sprite;
                        Sprite newSprite = null;
                        if (oldSprite)
                        {
                            var oldPivoit = new Vector2(oldSprite.pivot.x / oldSprite.rect.width, oldSprite.pivot.y / oldSprite.rect.height);
                            newSprite = UtilsUnity.LoadSpriteByIo(newPath, oldPivoit, oldSprite.pixelsPerUnit);
                        }
                        else
                            newSprite = UtilsUnity.LoadSpriteByIo(newPath, new Vector2(0.5f, 0.5f), 100);

                        m_ShipsPerfab[i].GetComponent<SpriteRenderer>().sprite = newSprite;
                    }
                }
            }
        }
    }


    public List<ArmTarget> CheckShipInRange(Vector3 position, float range, string selfInfluence)
    {
        List<ArmTarget> targets = new List<ArmTarget>();
        foreach(var ship in m_Ships)
        {
            if (ship == null || !ship.gameObject.activeSelf )
                continue;
            float resultDistance = (ship.transform.position - position).magnitude;
            if(resultDistance < range &&
                InfluenceMG.get().isHostile(selfInfluence, ship.m_ShipStruct.Influence))
            {
                ArmTarget target = new ArmTarget();
                target.Target = ship.gameObject;
                target.Type = ArmTarget.TargetType.SHIP;
                target.Distance = resultDistance;
                targets.Add(target);
            }
        }
        return targets;
    }
    public Ship GetShip(int index)
    {
        return m_Ships[index];
    }

    public void AddShip(Ship shipObj)
    {
        if (shipObj.IsShip)
            m_Ships.Add(shipObj);
        else
            m_NoShps.Add(shipObj);
    }
    public void RemoveShip(Ship shipObj)
    {
        m_Ships.Remove(shipObj);
    }

    public int FindShip(GameObject shipObj)
    {
        for(int i=0; i<m_Ships.Count; ++i)
        {
            if(m_Ships[i] == shipObj)
            {
                return i;
            }
        }
        return -1;
    }

    public void OnUnSceneLoaded(Scene scene)
    {
        m_Ships.Clear();
        m_NoShps.Clear();
    }


    public List<GameObject> GetAllShipList()
    {
        var object2 = Resources.LoadAll("Perfabs/Ships/Common/");
        List<GameObject> objs = new List<GameObject>();
        for(int i=0; i< object2.Length; ++i)
        {
            var gobj = object2[i] as GameObject;
            if (gobj != null)
                objs.Add(gobj);
        }
        return objs;
    }
}
